from QQLoginTool.QQtool import OAuthQQ
from mall import settings
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status
from .models import OauthQQUser,OauthSinaUser
from .serializers import OauthQQUsersSerializer,OauthSinaUsersSerializer
from rest_framework_jwt.settings import api_settings
from .utils import generate_safe_token

# Create your views here.

class OauthQQStatusAPIView(APIView):

    def get(self,request):

        state = request.query_params.get('state')

        if state is None:
            state = '/'

        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=state)

        auth_url = oauth.get_qq_url()

        return Response({'auth_url':auth_url})
class OauthQQUsersAPIView(GenericAPIView):

    serializer_class = OauthQQUsersSerializer

    def get(self,request):

        code = request.query_params.get('code')

        if code is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)


        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,)

        try:
            access_token1 = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token1)
        except Exception:
            return Response(status=status.HTTP_503_SERVICE_UNAVAILABLE)

        try:
            qq_user = OauthQQUser.objects.get(openid=openid)
        except OauthQQUser.DoesNotExist:
            #1.用户未绑定  (前端代码：this.access_token = response.data.access_token; 则后端应返回access_token)
            access_token = generate_safe_token(openid)
            return Response({'access_token':access_token})

        else:
            #.用户已绑定,手动生成令牌
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(qq_user.user)
            token = jwt_encode_handler(payload)

            data = {
                'token':token,
                'username':qq_user.user.username,
                'user_id':qq_user.user.id
            }

            return Response(data)



    def post(self,request):

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception = True)
        user = serializer.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        data = {
            'username':user.username,
            'user_id':user.id,
            'token':token
        }
        return Response(data)


class OauthSinaStatusAPIView(APIView):

    def get(self,request):

        state = request.query_params.get('state')

        if state is None:
            state = '/'
        # https://api.weibo.com / oauth2 / authorize?redirect_uri = http: // www.meiduo.site: 8080 / sina_callback.html & client_id = 3305669385 & state = /
        auth_url = settings.SINA_CODE_API \
                   +'?'\
                   +'client_id=' + settings.SINA_CLIENT_KEY \
                   +'&redirect_uri=' + settings.SINA_REDIRECT_URI\
                   +'&state=' + state

        return Response(data={'auth_url':auth_url})
class OauthSinaUsersAPIView(GenericAPIView):
    serializer_class = OauthSinaUsersSerializer

    def get(self,request):

        code = request.query_params.get('code')
        if code is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        access_url = settings.SINA_ACCESS_TOKEN_API \
                     +'?'\
                     +'client_id='+settings.SINA_CLIENT_KEY\
                     +'&client_secret='+settings.SINA_CLIENT_SECRET\
                     +'&grant_type=authorization_code'\
                     +'&code='+code\
                     +'&redirect_uri='+settings.SINA_REDIRECT_URI

        import urllib.request
        import urllib.parse
        import ssl
        import json

        context = ssl._create_unverified_context()
        values = {  }
        data = urllib.parse.urlencode(values).encode('ascii')
        req = urllib.request.Request(access_url, data=data)

        with  urllib.request.urlopen(req, context=context) as response:
            html = response.read()

        resp = json.loads(html.decode())
        try:
            access_token1 = resp.get('access_token')
        except Exception:
            return Response(status=status.HTTP_503_SERVICE_UNAVAILABLE)

        try:
            sina_user = OauthSinaUser.objects.get(access_token=access_token1)
        except OauthSinaUser.DoesNotExist:
            #1.用户未绑定  (前端代码：this.access_token = response.data.access_token; 则后端应返回access_token)
            access_token = generate_safe_token(access_token1)
            return Response({'access_token':access_token})

        else:
            #.用户已绑定,手动生成令牌
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(sina_user.user)
            token = jwt_encode_handler(payload)

            data = {
                'token':token,
                'username':sina_user.user.username,
                'user_id':sina_user.user.id
            }

            return Response(data)



    def post(self,request):

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception = True)
        user = serializer.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        data = {
            'username':user.username,
            'user_id':user.id,
            'token':token
        }
        return Response(data)






